package ptvv.system;

import java.util.Vector;

public class ConcurrentComponent extends DefPortAutomaton {
	Vector<ThreadAndClass> daAL;
	Configuration config;
	ThreadAndClass threadAndClass;
	int origNumPorts;
	//boolean shouldRepeat = false;

	public ConcurrentComponent(Configuration config) {
		this.setName("Component");
		threadAndClass = new ThreadAndClass(this, Thread.currentThread());
		this.config = config;
		daAL = config.daAL;
		origNumPorts = Configuration.countOrigInputs(config);
		if (config.shouldRepeat)
			this.repeatBool = true;
		for (int i = 0; i < config.intraconnections.size(); i++) {
			Port intraconn = config.intraconnections.get(i);

			if (intraconn.porttype == Port.type.input) {
				this.addInputPort();
			} else if (intraconn.porttype == Port.type.output) {

				// use port num
				this.addOutputPort();
				this.addInputPort();
				int portNum = intraconn.portNum + origNumPorts; // port on
																// receiver
				// daAL.get(intraconn.inQuestion).autoclass.addOutputPort();
				daAL.get(intraconn.inQuestion).autoclass.setOutputPort(
						threadAndClass, intraconn.portNum, portNum); // figure

			}
		}

		for (InitialCondition ic : config.initialConditions) {
			if (ic.message != null)
				daAL.get(ic.receiver).autoclass.addInput(ic.message, ic.port);
			if (ic.shouldStart)
				daAL.get(ic.receiver).autoclass.addEvent("START");
		}
	}

	@Override
	public void starting() throws InterruptedException {
		// System.out.println("End starting");
	}

	@Override
	public void ready() throws InterruptedException {
		// TODO Auto-generated method stub
		// eventQueue.take(); // waiting for start

	}

	@Override
	public void running() throws InterruptedException {
		// TODO Auto-generated method stub

		for (ThreadAndClass da : daAL) { // checking if terminated
			if (da.autothread.getState() == Thread.State.TERMINATED)
				da.restartThread();
			da.autothread.start();
			// for the concurrent aspect
			da.autoclass.addEvent("START");
		}

		for (ThreadAndClass da : daAL) {
			// if (da.autothread.isAlive()) {
			System.out.println("Waiting for: " + da.autothread.getName() + " "
					+ da.autoclass.getName() + "..");
			da.autothread.join();
			System.out.println("..got it.");
			// }
		}
	}

	@Override
	public void suspended() throws InterruptedException {
		// TODO Auto-generated method stub

	}

	@Override
	public void end() throws InterruptedException {
		// TODO Auto-generated method stub
		System.out.println(this.origNumPorts + " and now-> "
				+ this.outputPorts.size());

		// System.out.println(this.inputPorts.get(index));
		// repeatBool = true;
		// if (repeatBool)
		// for (int i = 0; i < outputPorts.size(); i++) {
		// // OutputPort outport = outputPorts.get(i);
		// //this.addInput(message, i);
		// }
		System.out.println("Entering Sleep");
		// Thread.sleep(1000);
		System.out.println("--");

		for (int i = this.origNumPorts; i < this.inputPorts.size(); i++) {
			String temp = this.inputPorts.get(i).queue.poll();
			if (temp != null)
				this.outputPorts.get(i - origNumPorts).queue.add(temp);
			System.out.println(temp);

		}

	}

	@Override
	public void dead() throws InterruptedException {
		// TODO Auto-generated method stub
		logger.log("SHUTDOWN");

	}

	public static void main(String[] args) {
		ConcurrentComponent one = new ConcurrentComponent(
				Configuration.ConfigurationOne());
		// Component two = new Component(new Configuration());

		// ThreadAndClass first = new ThreadAndClass(new Component(
		// new Configuration()));
		// ThreadAndClass second = new ThreadAndClass(new Component(
		// new Configuration()));
		// first.autoclass.addOutputPort(second, 1);
		(new Thread(one)).start();
		// (new Thread(two)).start();

	}
}
